package com.example.image;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import com.example.image.utils.UriUtils;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class ImageCreator {
    private static final int TAG_KEY_URI = R.id.imageloader_uri;
    private int targetWidth;
    private int targetHeight;
    private final Uri uri;
    private Drawable placeholderDrawable;
    private final Handler handler = new Handler(Looper.getMainLooper());


    public volatile static   ThreadPoolExecutor sThreadPoolExecutor;
    private Context mContext;

    public  static ThreadPoolExecutor getsThreadPoolExecutor() {

        if (sThreadPoolExecutor == null) {
            synchronized (ImageTan.class) {
                if (sThreadPoolExecutor == null) {
                    sThreadPoolExecutor
                            = new ThreadPoolExecutor(3,5,1, TimeUnit.SECONDS,
                            new LinkedBlockingQueue<>());
                }
            }
        }
        return sThreadPoolExecutor;
    }

    public volatile static   ImageCreator instance;

    public  static ImageCreator getInstance(Uri uri) {

        if (instance == null) {
            synchronized (ImageTan.class) {
                if (instance == null) {
                    instance
                            = new ImageCreator(uri);
                }
            }
        }
        return instance;
    }

    private Bitmap bm;


    private ImageCreator(Uri uri){
        this.uri = uri;
    }

    public ImageCreator resize(int targetWidth,int targetHeight){
        if (targetWidth < 0) {
            throw new IllegalArgumentException("Width must be positive number or 0.");
        }
        if (targetHeight < 0) {
            throw new IllegalArgumentException("Height must be positive number or 0.");
        }
        if (targetHeight == 0 && targetWidth == 0) {
            throw new IllegalArgumentException("At least one dimension has to be positive number.");
        }
        this.targetWidth = targetWidth;
        this.targetHeight = targetHeight;
        return this;
    }


    public ImageCreator setContext(Context context){
        mContext = context;
        return this;
    }

    public ImageCreator placeholder(@NonNull Drawable placeholderDrawable) {
        this.placeholderDrawable = placeholderDrawable;
        return this;
    }

    public void into(ImageView target){
        target.setImageDrawable(placeholderDrawable);
        bm = PicLru.getInstance().getPic(uri.toString());
        target.setTag(TAG_KEY_URI, uri);
        if (bm == null){
            getsThreadPoolExecutor().execute(() -> bitmapFactory(uri,target,targetWidth,targetHeight));
        }else {
            target.setImageBitmap(bm);
            target.setScaleType(ImageView.ScaleType.CENTER_CROP);
        }
    }

    private void bitmapFactory(Uri imageUri,ImageView target,int targetWidth,int targetHeight){

        String imagePath = UriUtils. getFilePathFromURI(mContext, imageUri);

        // 配置压缩的参数
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true; //获取当前图片的边界大小，而不是将整张图片载入在内存中，避免内存溢出
        BitmapFactory.decodeFile(imagePath, options);
        if (options.outWidth == -1){
            bm = getVideoThumbnail(imagePath);
        }else {
            options.inJustDecodeBounds = false;
            //inSampleSize的作用就是可以把图片的长短缩小inSampleSize倍，所占内存缩小inSampleSize的平方
            options.inSampleSize = calculateSampleSize(options,targetWidth,targetHeight);
            bm = BitmapFactory.decodeFile(imagePath, options); // 解码文件
        }
        PicLru.getInstance().cachePic(uri.toString(),bm);

        handler.post(() -> {
            Uri uriJudge = (Uri) target.getTag(TAG_KEY_URI);
            if (uriJudge==uri) {
                target.setImageBitmap(bm);
                target.setScaleType(ImageView.ScaleType.CENTER_CROP);
            }
        });

    }

    private int calculateSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        int sampleSize = 1;
        int picWidth = options.outWidth;
        int picHeight = options.outHeight;
        if (picWidth > reqWidth || picHeight > reqHeight) {
            int halfPicWidth = picWidth / 2;
            int halfPicHeight = picHeight / 2;
            while (halfPicWidth / sampleSize > reqWidth || halfPicHeight / sampleSize > reqHeight) {
                sampleSize *= 2;
            }
        }
        return sampleSize;
    }

    public Bitmap getVideoThumbnail(String filePath) {
        Bitmap bitmap = null;
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(filePath);
            bitmap = retriever.getFrameAtTime(TimeUnit.MILLISECONDS.toMicros(1));
        }
        catch(IllegalArgumentException e) {
            e.printStackTrace();
        }
        finally {
            try {
                retriever.release();
            }
            catch (RuntimeException e) {
                e.printStackTrace();
            }
        }
        return bitmap;
    }
}
